package com.haohan.cloud.scm.api.crm.trans;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.haohan.cloud.scm.api.constant.enums.common.UseStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.crm.DataReportEnum;
import com.haohan.cloud.scm.api.constant.enums.crm.DynamicTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.manage.MerchantPdsTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.manage.MerchantStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.market.LevelEnum;
import com.haohan.cloud.scm.api.constant.enums.market.SexEnum;
import com.haohan.cloud.scm.api.constant.enums.opc.YesNoEnum;
import com.haohan.cloud.scm.api.constant.enums.saleb.BuyerTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.saleb.PayPeriodEnum;
import com.haohan.cloud.scm.api.crm.dto.CustomerDTO;
import com.haohan.cloud.scm.api.crm.dto.CustomerMerchantDTO;
import com.haohan.cloud.scm.api.crm.entity.*;
import com.haohan.cloud.scm.api.crm.vo.CustomerVO;
import com.haohan.cloud.scm.api.manage.entity.Merchant;
import com.haohan.cloud.scm.api.saleb.entity.Buyer;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import io.swagger.annotations.ApiModelProperty;
import lombok.experimental.UtilityClass;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Map;
import java.util.Set;

/**
 * @author dy
 * @date 2019/9/27
 */
@UtilityClass
public class CrmCustomerTrans {

    /**
     * 根据客户初始设置 客户层级关系
     *
     * @param customer
     * @param parentId
     * @return
     */
    public CustomerLevel initLevel(Customer customer, String parentId) {
        CustomerLevel level = new CustomerLevel();
        level.setCustomerSn(customer.getCustomerSn());
        level.setCustomerName(customer.getCustomerName());
        level.setParentId(parentId);
        level.setSort("100");
        level.setLevel(LevelEnum.oneStar);
        return level;
    }

    /**
     * 设置客户送货地址 到销售订单
     *
     * @param order
     * @param address
     */
    public void fetchAddress(SalesOrder order, CustomerAddress address) {
        order.setLinkmanId(address.getLinkmanId());
        order.setLinkmanName(address.getLinkman());
        order.setAddress(address.getAddress());
        order.setTelephone(address.getTelephone());
    }


    /**
     * 根据客户信息设置默认主要联系人
     *
     * @param customer
     * @return
     */
    public CustomerLinkman defaultLinkman(Customer customer) {
        CustomerLinkman linkman = new CustomerLinkman();
        linkman.setCustomerSn(customer.getCustomerSn());
        linkman.setName(customer.getContact());
        linkman.setSex(SexEnum.man);
        linkman.setTelephone(customer.getTelephone());
        linkman.setAddress(customer.getAddress());
        linkman.setPrimaryFlag(YesNoEnum.yes);
        return linkman;
    }

    /**
     * 根据送货地址默认联系人
     *
     * @param address
     * @return
     */
    public CustomerLinkman defaultLinkman(CustomerAddress address) {
        CustomerLinkman linkman = new CustomerLinkman();
        linkman.setCustomerSn(address.getCustomerSn());
        linkman.setName(address.getLinkman());
        linkman.setSex(SexEnum.man);
        linkman.setTelephone(address.getTelephone());
        linkman.setAddress(address.getAddress());
        linkman.setPrimaryFlag(YesNoEnum.no);
        return linkman;
    }

    /**
     * 根据客户信息设置默认送货地址
     *
     * @param customer
     * @param linkmanId
     * @return
     */
    public CustomerAddress defaultAddress(Customer customer, String linkmanId) {
        CustomerAddress address = new CustomerAddress();
        address.setLinkmanId(linkmanId);

        address.setCustomerSn(customer.getCustomerSn());
        address.setLinkman(customer.getContact());
        address.setPhone(customer.getPhoneNumber());
        address.setProvince(customer.getProvince());
        address.setCity(customer.getCity());
        address.setDistrict(customer.getDistrict());
        address.setStreet(customer.getStreet());
        address.setAddress(customer.getAddress());
        address.setPosition(customer.getPosition());
        address.setTelephone(customer.getTelephone());
        address.setDefaultFlag(YesNoEnum.yes);
        return address;
    }

    public CustomerVO transCustomer(CustomerDTO customer) {
        CustomerVO customerVO = new CustomerVO();
        BeanUtil.copyProperties(customer, customerVO);
        // 是否标注定位
        customerVO.setPositionFlag(null != customer.getPosition());
        return customerVO;
    }

    /**
     * 字符串转日期  yyyy-MM
     *
     * @param month yyyy-MM
     * @return
     */
    public LocalDate transMonth(String month) {
        LocalDate date;
        if (StrUtil.isEmpty(month)) {
            return null;
        }
        int y, m;
        try {
            String[] start = month.split("-");
            y = Integer.parseInt(start[0]);
            m = Integer.parseInt(start[1]);
            date = LocalDate.of(y, m, 1);
        } catch (Exception e) {
//            e.printStackTrace();
            throw new ErrorDataException("日期格式有误! 格式为yyyy-MM");
        }
        return date;
    }

    /**
     * 转换月份字符串 为月份时间段
     *
     * @param startMonth yyyy-MM
     * @param endMonth   yyyy-MM
     * @return
     */
    public LocalDate[] transMonthSpan(String startMonth, String endMonth) {
        // 起止时间处理
        LocalDate startDate;
        LocalDate endDate;
        startDate = transMonth(startMonth);
        endDate = transMonth(endMonth);

        LocalDate lastDate = LocalDate.now();
        // 默认当前 六个月  最大12个月
        if (null == startDate) {
            endDate = lastDate;
            startDate = endDate.minusMonths(5);
        } else if (null == endDate) {
            endDate = startDate.plusMonths(5);
        } else if (startDate.until(endDate).getMonths() > 12) {
            endDate = startDate.plusMonths(11);
        }
        // 截止当前时间
        if (endDate.isAfter(lastDate)) {
            endDate = lastDate;
        }
        // 月初、月末
        startDate = startDate.with(TemporalAdjusters.firstDayOfMonth());
        endDate = endDate.with(TemporalAdjusters.lastDayOfMonth());
        return new LocalDate[]{startDate, endDate};
    }

    /**
     * 根据客户信息初始化商家
     *
     * @param customer
     * @return
     */
    public static Merchant initMerchant(Customer customer) {
        Merchant merchant = new Merchant();
        merchant.setMerchantName(customer.getCustomerName());
        merchant.setAddress(customer.getAddress());
        merchant.setContact(customer.getContact());
        merchant.setTelephone(customer.getTelephone());
        merchant.setBizDesc(customer.getBizDesc());
        merchant.setStatus(MerchantStatusEnum.stayAudit);
        //  merchantType  prodType productLine暂不设置
        merchant.setIsAutomaticOrder(YesNoEnum.no);
        merchant.setPdsType(MerchantPdsTypeEnum.general);
        return merchant;
    }

    /**
     * 初始化客户商家关系
     *
     * @param customer
     * @param merchant
     * @return
     */
    public static CustomerMerchantRelation init(Customer customer, Merchant merchant) {
        CustomerMerchantRelation relation = new CustomerMerchantRelation();
        relation.setCustomerId(customer.getId());
        relation.setCustomerSn(customer.getCustomerSn());
        relation.setCustomerName(customer.getCustomerName());
        relation.setMerchantId(merchant.getId());
        relation.setMerchantName(merchant.getMerchantName());
        return relation;
    }

    /**
     * 初始设置业务动态  内容格式
     *
     * @param customerSn
     * @param stateType
     * @param sourceSn
     * @param telephone
     * @param reportMan
     * @param totalAmount
     * @param totalNum
     * @param addFlag     true 为新增
     * @return
     */
    public static CustomerDynamicState initCustomerDynamic(String customerSn, DynamicTypeEnum stateType, String sourceSn,
                                                           String telephone, String reportMan, BigDecimal totalAmount,
                                                           Integer totalNum, boolean addFlag) {
        CustomerDynamicState result = new CustomerDynamicState();
        result.setCustomerSn(customerSn);
        result.setStateType(stateType);
        result.setSourceSn(sourceSn);
        result.setTelephone(telephone);
        result.setReportMan(reportMan);
        String edit = addFlag ? "新增" : "修改";
        String type = stateType == DynamicTypeEnum.order ? "订购" : "上报";
        String content = StrUtil.format("{}{}:{}{}个品种, 总金额{}元", edit, sourceSn, type, totalNum, totalAmount);
        result.setContent(content);
        return result;
    }

    /**
     * 转换 业务动态类型  根据上报类型
     *
     * @param reportType
     * @return
     */
    public static DynamicTypeEnum transDynamicType(DataReportEnum reportType) {
        DynamicTypeEnum type = null;
        switch (reportType) {
            case stock:
                type = DynamicTypeEnum.stock;
                break;
            case sales:
                type = DynamicTypeEnum.sales;
                break;
            case competition:
                type = DynamicTypeEnum.competition;
                break;
            default:
        }
        return type;
    }

    /**
     * 比较不同
     *
     * @param o1
     * @param o2
     * @return String[]
     * 0 注释   @ApiModelProperty
     * 1 o1
     * 2 o2
     */
    public static String[] compareProperty(Object o1, Object o2, Class clazz, String propertyName) {
        // 枚举处理
        if (o1 instanceof Enum) {
            o1 = ReflectUtil.getFieldValue(o1, "desc");
        }
        if (o2 instanceof Enum) {
            o2 = ReflectUtil.getFieldValue(o2, "desc");
        }
        String v1 = null == o1 ? "" : o1.toString();
        String v2 = null == o2 ? "" : o2.toString();
        // 修改前后未变,或修改后值为空 都为未实际修改
        if (v1.equals(v2) || StrUtil.isEmpty(v2)) {
            return new String[0];
        }
        // 注释
        Object a = AnnotationUtil.getAnnotationValue(ReflectUtil.getField(clazz, propertyName), ApiModelProperty.class);
        String[] result = new String[3];
        result[0] = a == null ? propertyName : a.toString();
        result[1] = v1;
        result[2] = v2;
        return result;
    }

    /**
     * 实体类转
     *
     * @param source
     * @param map
     * @param ignoreProperties
     */
    public static Map<String, Object> transToMap(Object source, Map<String, Object> map, String[] ignoreProperties) {
        return BeanUtil.beanToMap(source, map, true, key -> StrUtil.equalsAny(key, ignoreProperties) ? null : key);
    }

    /**
     * 客户编号列表转set
     * 为空时设置默认客户编号(市场总监)
     *
     * @param customerSnSet @NutNoll
     * @param customerSn
     * @return
     */
    public Set<String> ownCustomerSnSet(Set<String> customerSnSet, String customerSn) {
        if (CollUtil.isEmpty(customerSnSet) && StrUtil.isNotEmpty(customerSn)) {
            customerSnSet.add(customerSn);
        }
        return customerSnSet;
    }


    public static Buyer initBuyer(CustomerMerchantDTO merchantDTO, CustomerAddress address) {
        Buyer buyer = new Buyer();
        buyer.setPmId(merchantDTO.getPmId());
        buyer.setMerchantId(merchantDTO.getMerchantId());
        buyer.setMerchantName(merchantDTO.getMerchantName());
        buyer.setBuyerName(StrUtil.format("{}-{}", merchantDTO.getCustomerName(), address.getLinkman()));
        buyer.setShortName(address.getLinkman());
        buyer.setContact(address.getLinkman());
        buyer.setTelephone(address.getTelephone());
        buyer.setPayPeriod(PayPeriodEnum.day);
        buyer.setPayDay("1");
        buyer.setAddress(address.getAddress());
        buyer.setNeedConfirmation(YesNoEnum.yes);
        buyer.setNeedPay(YesNoEnum.yes);
        buyer.setBuyerType(BuyerTypeEnum.employee);
        buyer.setNeedPush(YesNoEnum.yes);
        buyer.setStatus(UseStatusEnum.enabled);
        buyer.setSort("100");
        buyer.setRemarks("客户联系人转换来");
        buyer.setArea(address.getProvince());
        // 定位处理
        if (StrUtil.isNotEmpty(address.getPosition())) {
            String[] post = StrUtil.split(address.getPosition(), StrUtil.COMMA);
            buyer.setLongitude(post[0]);
            buyer.setLatitude(post[1]);
        }
        return buyer;
    }
}
